package cn.jtfadmin.base.lang.common.utils;

import org.apache.commons.collections.map.HashedMap;
import org.apache.poi.hwpf.HWPFDocumentCore;
import org.apache.poi.hwpf.converter.AbstractWordUtils;
import org.apache.poi.hwpf.converter.PicturesManager;
import org.apache.poi.hwpf.converter.WordToHtmlConverter;
import org.apache.poi.hwpf.usermodel.PictureType;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.XMLHelper;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFPictureData;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlOptions;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody;
import org.w3c.dom.Document;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;
import java.util.Base64;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * word 工具， 合并多个文档
 *
 * @author jtf
 * @since 0.0.1
 */
public class WordUtils {

    /**
     * 合并多个word 07版本， 用来补充easypoi 中word功能<br/>
     * bug 图片合成时大小未变化
     *
     * @param documents word07 版本
     * @return 合并后word
     */
    public static XWPFDocument meger(XWPFDocument... documents) {
        if (Objects.isNull(documents)) {
            return null;
        }
        XWPFDocument result = documents[0];
        for (int i = 1; i < documents.length; i++) {
            result.createParagraph().setPageBreak(true);
            CTBody body = result.getDocument().getBody();
            XWPFDocument add = documents[i];
            List<XWPFPictureData> allPictures = add.getAllPictures();
            Map<String, String> picIds = new HashedMap();
            for (XWPFPictureData allPicture : allPictures) {
                int pictureType = allPicture.getPictureType();
                byte[] data = allPicture.getData();
                String relationId = add.getRelationId(allPicture);
                String picIdNew = null;
                try {
                    picIdNew = result.addPictureData(data, pictureType);
                } catch (InvalidFormatException e) {
                    throw new RuntimeException(e);
                }
                picIds.put(relationId, picIdNew);
            }
            CTBody append = add.getDocument().getBody();
            XmlOptions optionsOuter = new XmlOptions();
            optionsOuter.setSaveOuter();
            String appendString = append.xmlText(optionsOuter);
            String srcString = body.xmlText();
            String prefix = srcString.substring(0, srcString.indexOf(">") + 1);
            String mainPart = srcString.substring(srcString.indexOf(">") + 1, srcString.lastIndexOf("<"));
            String sufix = srcString.substring(srcString.lastIndexOf("<"));
            String addPart = appendString.substring(appendString.indexOf(">") + 1, appendString.lastIndexOf("<"));
            CTBody makeBody = null;
            for (Map.Entry<String, String> entry : picIds.entrySet()) {
                addPart.replaceAll("r:emberd=\"" + entry.getKey() + "\"", "r:emberd=\"" + entry.getValue() + "\"");
            }
            try {

                makeBody = (CTBody) CTBody.Factory.parse(prefix + mainPart + addPart
                        + sufix);
            } catch (XmlException e) {
                throw new RuntimeException(e);
            }
            body.set(makeBody);

        }
        return result;
    }



    /**
     * 将03版的word 转换为html
     * @param is 输入流
     * @return html
     */
    public static InputStream toHtml03(InputStream is)  {

        try(InputStream inputStream = is; ByteArrayOutputStream outputStream = new ByteArrayOutputStream()){
            DocumentBuilder docBuild = XMLHelper.getDocumentBuilderFactory().newDocumentBuilder();
            HWPFDocumentCore wordDocument = AbstractWordUtils.loadDoc( inputStream );
            WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(docBuild.newDocument());
            wordToHtmlConverter.setPicturesManager(new PicturesManager() {
                @Override
                public String savePicture(byte[] content, PictureType pictureType, String suggestedName, float widthInches, float heightInches) {

                        StringBuilder sb = new StringBuilder();
                        sb.append("data:")
                                .append(pictureType.getMime())
                                .append(";base64,")
                                .append(new String(Base64.getEncoder().encode(content)));
                        return sb.toString();


                }
            });
            wordToHtmlConverter.processDocument(wordDocument);
            Document document = wordToHtmlConverter.getDocument();
            DOMSource domSource = new DOMSource( document );
            StreamResult streamResult = new StreamResult( outputStream);

            TransformerFactory tf = TransformerFactory.newInstance();
            Transformer serializer = tf.newTransformer();
            serializer.setOutputProperty( OutputKeys.ENCODING, "UTF-8" );
            serializer.setOutputProperty( OutputKeys.INDENT, "yes" );
            serializer.setOutputProperty( OutputKeys.METHOD, "html" );
            serializer.transform( domSource, streamResult );
            return new ByteArrayInputStream(outputStream.toByteArray());

        }catch (Exception e){
            throw new RuntimeException(e);
        }


    }
/////////////// xdocreport 版本2.0.2 不支持poi5.0 ,支持3.x
//    /**
//     * 将07版的word 转换为html
//     * @param is 输入流
//     * @return html
//     */
//    public static InputStream toHtml07(InputStream is)  {
//
//        try(InputStream inputStream = is; ByteArrayOutputStream outputStream = new ByteArrayOutputStream()){
//            XWPFDocument document = new XWPFDocument(inputStream);
//            XHTMLOptions options = XHTMLOptions.create();
//            String temDirName = RandomStringUtils.randomNumeric(6);
//            // 存放图片的文件夹
//            options.setExtractor(new FileImageExtractor(new File(SystemUtils.getJavaIoTmpDir(), temDirName)));
//            // html中图片的路径
//            options.URIResolver(new IURIResolver() {
//                @Override
//                public String resolve(String uri) {
//                    File file = Paths.get(SystemUtils.getJavaIoTmpDir().getAbsolutePath(), temDirName, uri).toFile();
//                    try(InputStream io = new FileInputStream(file)){
//                        byte[] bytes = StreamUtils.copyToByteArray(io);
//                        PictureType pictureType = PictureType.findMatchingType(bytes);
//                        StringBuilder sb = new StringBuilder();
//                        sb.append("data:")
//                                .append(pictureType.getMime())
//                                .append(";base64,")
//                                .append(new String(Base64.getEncoder().encode(bytes)));
//                        return sb.toString();
//                    }catch (IOException e){
//                        return null;
//                    }
//                }
//            });
//            FileSystemUtils.deleteRecursively(Paths.get(SystemUtils.getJavaIoTmpDir().getAbsolutePath(), temDirName));
//            IXWPFConverter<XHTMLOptions> xhtmlConverter =  XHTMLConverter.getInstance();
//            xhtmlConverter.convert(document, outputStream, options);
//
//            return new ByteArrayInputStream(outputStream.toByteArray());
//
//        }catch (Exception e){
//            throw new RuntimeException(e);
//        }
//
//
//    }
}
